package net.vtstar.vtcloud.framework.system.api.util;

import com.google.common.base.Ascii;
import com.google.common.base.Splitter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetAddress;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;

/**
 * com.linecorp.armeria.common.SystemPropertyFlagsProvider
 */
public final class SystemPropertyFlagsProvider implements FlagsProvider {

    private static final Logger logger = LoggerFactory.getLogger(SystemPropertyFlagsProvider.class);
    private static final String PREFIX = "net.vtstar.vtcloud.config.";
    private static final Splitter CSV_SPLITTER = Splitter.on(',').trimResults().omitEmptyStrings();

    @Override
    public int priority() {
        return Integer.MAX_VALUE;
    }

    @Override
    public String name() {
        return "sysprops";
    }

    @Override
    public Predicate<InetAddress> preferredIpV4Addresses() {
        final String val = getNormalized("preferredIpV4Addresses");
        if (val == null) {
            return null;
        }
        final List<Predicate<InetAddress>> preferredIpV4Addresses =
                CSV_SPLITTER.splitToList(val)
                        .stream()
                        .map(cidr -> {
                            try {
                                return InetAddressPredicates.ofCidr(cidr);
                            } catch (Exception e) {
                                logger.warn("Failed to parse a preferred IPv4: {}", cidr);
                            }
                            return null;
                        })
                        .filter(Objects::nonNull)
                        .toList();
        return switch (preferredIpV4Addresses.size()) {
            case 0 -> null;
            case 1 -> preferredIpV4Addresses.get(0);
            default -> inetAddress -> {
                for (Predicate<InetAddress> preferredIpV4Addr : preferredIpV4Addresses) {
                    if (preferredIpV4Addr.test(inetAddress)) {
                        return true;
                    }
                }
                return false;
            };
        };
    }

    private static String getNormalized(String name) {
        final String fullName = PREFIX + name;
        String value = System.getProperty(fullName);
        if (value != null) {
            value = Ascii.toLowerCase(value);
        }
        return value;
    }
}
